package com.mls.guardian.container;


import com.mls.guardian.ThreadFactoryExetend;
import com.mls.guardian.config.AppSTConfig;
import com.mls.guardian.config.MasterConfig;
import com.mls.guardian.config.NettyConfig;
import com.mls.guardian.config.SlaveConfig;
import com.mls.guardian.em.ContainerRole;
import com.mls.guardian.executor.master.*;
import com.mls.guardian.master.ClientDispatch;
import com.mls.guardian.project.ProjectConfigFactory;
import com.mls.guardian.protocol.CodeType;
import com.mls.guardian.remoting.netty.NettyServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by jl on 15/9/9.
 */
public class MasterContainer extends BaseContainer {
    private static final Logger log = LoggerFactory.getLogger(MasterContainer.class);

    //netty服务器
    private NettyServer nettyServer;

    private ExecutorService masterDefaultExecutor;
    protected ExecutorService serviceExecutor;
    protected MasterConfig masterConfig = new MasterConfig();
    private ClientDispatch clientDispatch;

    public MasterContainer(MasterConfig masterConfig, SlaveConfig slaveConfig, AppSTConfig appStConfig, NettyConfig nettyConfig) {
        super(appStConfig);
        this.masterConfig = masterConfig;
        //启动netty服务器
        nettyServer = new NettyServer(masterConfig.getMasterPort(), nettyConfig);
        clientDispatch = new ClientDispatch(this);

        this.role = ContainerRole.MASTER;
    }

    @Override
    public void startup() throws Exception {

        masterDefaultExecutor =
                Executors.newFixedThreadPool(this.masterConfig.getDefaultThreadPoolNums(),
                        new ThreadFactoryExetend("MasterDefault_"));

        serviceExecutor =
                Executors.newFixedThreadPool(10,
                        new ThreadFactoryExetend("MasterService_"));

        projectObjList = ProjectConfigFactory.createProjects();

        //启动appcontorller
        appController.startup(projectObjList);


        nettyServer.start();
        registerExcutor(nettyServer);
    }

    public void registerExcutor(NettyServer nettyServer) {
        nettyServer.registerExcutor(CodeType.SLAVE_HEAR_BEAT, new PingExecutor(this));

        nettyServer.registerExcutor(CodeType.CLIENT_INVALID, new InactiveExecutor(this));
        nettyServer.registerExcutorWithExecutorService(CodeType.START, new StartAppExecutor(this), masterDefaultExecutor);
        nettyServer.registerExcutorWithExecutorService(CodeType.RESTART, new RestartAppExecutor(this), masterDefaultExecutor);
        nettyServer.registerExcutorWithExecutorService(CodeType.STOP, new StopAppExecutor(this), masterDefaultExecutor);
        nettyServer.registerExcutorWithExecutorService(CodeType.SERVER_PROCESS_INFO, new ServerProcessInfoExecutor(this),masterDefaultExecutor);
        nettyServer.registerExcutor(CodeType.SEND_LOG, new SlaveLogExecutor(this));
        nettyServer.registerExcutor(CodeType.GET_BACKUP, new GetBackupExecutor(this));
        nettyServer.registerExcutor(CodeType.UPDATE_STATIC_FILE, new UpdateStaticFileExecutor(this));
        nettyServer.registerExcutor(CodeType.RESTORE, new RestoreAppExecutor(this));

        nettyServer.registerExcutor(CodeType.GET_FILE_INFO, new GetFileInfoExecutor(this));
        nettyServer.registerExcutor(CodeType.UPGRADE, new UpgradeExecutor(this));
        nettyServer.registerExcutor(CodeType.GET_UPGRADE_VERSION, new GetUpgradeVersionExcutor(this));
    }


    public ClientDispatch getClientDispatch() {
        return clientDispatch;
    }

    public ExecutorService getServiceExecutor() {
        return serviceExecutor;
    }

    public NettyServer getServer() {
        return nettyServer;
    }


    @Override
    public void shutdown() {
        nettyServer.shutdown();
        masterDefaultExecutor.shutdown();
        serviceExecutor.shutdown();
    }


}
